package com.chzc.mq;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.chzc.entity.DevilMessage;
import com.chzc.goods.mapper.GoodsMapper;
import com.chzc.goods.mapper.OrderInfoMapper;
import com.chzc.goods.service.RedisService;
import com.chzc.po.Goods;
import com.chzc.po.OrderInfo;
import com.chzc.po.User;
import com.chzc.server.DevilConsumer;
import com.chzc.server.DevilProducer;
import com.chzc.sys.service.IUserService;
import com.chzc.util.enums.KillEnum;
import com.chzc.util.properties.DevilMqProperties;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 项目启动时加载MQ监听器
 *
 * @author cv大魔王
 * @version 1.0
 * @date 2021/6/24 8:00
 */
@Service
@Slf4j
public class HsStarted {


    @Autowired
    private DevilMqProperties devilMqProperties;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IUserService userService;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private DevilProducer getProducerMQ;

    private static DevilProducer producer;


    /**
     * 消费订单
     *
     * @Async("taskExecutor")
     */
    @PostConstruct
    public void consumerOrderMessage() {
        //构造一个线程池
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        cachedThreadPool.execute(() -> {
            DevilConsumer consumer = new DevilConsumer("127.0.0.1", 7000, "GOODS_ORDER");
            consumer.start(new SimpleChannelInboundHandler<DevilMessage>() {
                @Override
                protected void channelRead0(ChannelHandlerContext channelHandlerContext, DevilMessage msg) throws Exception {
                    System.err.println("-->"+msg.getContent());
                    // 转java对象
                    GoodsOrderMQ goodsOrderMQ = JSON.parseObject(new String(msg.getContent(), StandardCharsets.UTF_8), GoodsOrderMQ.class);
                    System.err.println("-->"+goodsOrderMQ);
                    // 获取抢购名单
                    BoundZSetOperations<String, User> operations = redisTemplate.boundZSetOps(KillEnum.goods_point_rank_real_ + goodsOrderMQ.getGoods().getId());
                    // 获取抢购名次
                    Integer score = (Integer) redisService.get(KillEnum.goods_ranking_ + goodsOrderMQ.getGoods().getId());
                    redisService.incr(KillEnum.goods_ranking_ + goodsOrderMQ.getGoods().getId(), 1);

                    User user = userService.findUserById(goodsOrderMQ.getUserId());
                    if (score <= 100) {
                        user.setGoodsDiscount("1折");
                    } else if (score <= 500) {
                        user.setGoodsDiscount("5折");
                    } else if (score <= 1000) {
                        user.setGoodsDiscount("8折");
                    } else {
                        user.setGoodsDiscount("原价");
                    }

                    try {
                        // 加入抢购名单
                        if (score<=1000){
                            operations.add(user, score);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    // 库存-1
                    goodsOrderMQ.getGoods().setGoodsStock(goodsOrderMQ.getGoods().getGoodsStock() - 1);
                    // 大于0执行库存递减
                    UpdateWrapper<Goods> wrapper = new UpdateWrapper<>();
                    wrapper.eq("id", goodsOrderMQ.getGoods().getId());
                    wrapper.gt("goods_stock", 0);
                    int i = goodsMapper.update(goodsOrderMQ.getGoods(), wrapper);


                    if (i < 0) {
                        // 扣减失败
                        // return new Result(false, StatusCode.KILL_FAIL.getCode(), StatusCode.KILL_FAIL.getMessage());
                        log.error("订单扣减失败，订单信息--->" + goodsOrderMQ.getGoods());
                    }
                    // 添加订单
                    commonRecordKillSuccessInfo(goodsOrderMQ.getGoods(), goodsOrderMQ.getAddress(), goodsOrderMQ.getUserId(), goodsOrderMQ.getOrderId(), score);
                }
            });
        });
    }

    /**
     * 秒杀后生成的订单
     *
     * @param goods   秒杀商品信息
     * @param address 收货地址
     * @param userId  用户id
     * @param orderId 订单编号
     * @param score   用户抢购名次
     */
    public void commonRecordKillSuccessInfo(Goods goods, String address, String userId, String orderId, int score) {
        OrderInfo orderInfo = new OrderInfo();

        // 商品秒杀价格
        orderInfo.setGoodsOldPrice(goods.getSeckillPrice());

        // 商品秒杀+折扣价格
        if (score <= 100) {
            orderInfo.setGoodsDiscount("1折");
            orderInfo.setGoodsPrice(goods.getSeckillPrice().multiply(BigDecimal.valueOf(0.1)));
        } else if (score <= 500) {
            orderInfo.setGoodsDiscount("5折");
            orderInfo.setGoodsPrice(goods.getSeckillPrice().multiply(BigDecimal.valueOf(0.5)));
        } else if (score <= 1000) {
            orderInfo.setGoodsDiscount("8折");
            orderInfo.setGoodsPrice(goods.getSeckillPrice().multiply(BigDecimal.valueOf(0.8)));
        } else {
            orderInfo.setGoodsDiscount("原价");
            orderInfo.setGoodsPrice(goods.getSeckillPrice());
        }

        orderInfo.setId(orderId);
        orderInfo.setUserId(userId);
        orderInfo.setGoodsId(goods.getId());
        orderInfo.setDeliveryAddrId(address);
        orderInfo.setGoodName(goods.getGoodsTitle());
        orderInfo.setGoodsCount(1);

        orderInfo.setOrderChannel(1);
        orderInfo.setStatus(0);
        orderInfo.setGoodsImg(goods.getGoodsImg());
        orderInfo.setCreateDate(new Date());
        orderInfoMapper.insert(orderInfo);
    }
}
